/**
 * 用户界面交互模块
 * @module ui
 */

import TuringMachine from './turingMachine.js';
import Assembler from './assembler.js';
import { DIRECTION, ERROR_MESSAGES } from './constants.js';
import { loadInstructions, saveInstructions, getHistory, clearHistory } from './storage.js';

/**
 * 用户界面控制器类
 */
class UIController {
    constructor() {
        this.turingMachine = new TuringMachine();
        this.assembler = new Assembler(this.turingMachine);
        this.animationFrameId = null;
        this.executionSpeed = 500; // 毫秒
        this.isExecuting = false;
        
        this.initElements();
        this.bindEvents();
        this.updateUI();
    }

    /**
     * 初始化DOM元素引用
     */
    initElements() {
        // 控制按钮
        this.startBtn = document.getElementById('startBtn');
        this.pauseBtn = document.getElementById('pauseBtn');
        this.stepBtn = document.getElementById('stepBtn');
        this.resetBtn = document.getElementById('resetBtn');
        this.haltBtn = document.getElementById('haltBtn');
        
        // 速度控制
        this.speedSlider = document.getElementById('speedSlider');
        this.speedValue = document.getElementById('speedValue');
        
        // 移动控制
        this.moveLeftBtn = document.getElementById('moveLeftBtn');
        this.moveRightBtn = document.getElementById('moveRightBtn');
        this.moveSteps = document.getElementById('moveSteps');
        
        // 缓存操作
        this.loadToCacheBtn = document.getElementById('loadToCacheBtn');
        this.loadPosition = document.getElementById('loadPosition');
        this.loadLength = document.getElementById('loadLength');
        this.writeFromCacheBtn = document.getElementById('writeFromCacheBtn');
        this.writePosition = document.getElementById('writePosition');
        this.clearCacheBtn = document.getElementById('clearCacheBtn');
        this.editCacheBtn = document.getElementById('editCacheBtn');
        
        // 数据输入
        this.inputData = document.getElementById('inputData');
        this.inputPosition = document.getElementById('inputPosition');
        this.writeDataBtn = document.getElementById('writeDataBtn');
        
        // 字节大小
        this.byteSizeInput = document.getElementById('byteSizeInput');
        
        // 状态显示
        this.currentState = document.getElementById('currentState');
        this.currentSymbol = document.getElementById('currentSymbol');
        this.headPosition = document.getElementById('headPosition');
        this.stepCount = document.getElementById('stepCount');
        this.byteSize = document.getElementById('byteSize');
        this.cacheSize = document.getElementById('cacheSize');
        
        // 纸带显示
        this.tapeCanvas = document.getElementById('tapeCanvas');
        this.tapeCtx = this.tapeCanvas.getContext('2d');
        
        // 缓存显示
        this.cacheView = document.getElementById('cacheView');
        
        // 命令输入
        this.commandInput = document.getElementById('commandInput');
        this.executeCommandBtn = document.getElementById('executeCommandBtn');
        this.addInstructionBtn = document.getElementById('addInstructionBtn');
        
        // 历史记录
        this.commandHistory = document.getElementById('commandHistory');
        this.clearHistoryBtn = document.getElementById('clearHistoryBtn');
        
        // 汇编输入
        this.assemblyInput = document.getElementById('assemblyInput');
        this.runAssemblyBtn = document.getElementById('runAssemblyBtn');
        this.compileAssemblyBtn = document.getElementById('compileAssemblyBtn');
        
        // 高级语言
        this.highlevelInput = document.getElementById('highlevelInput');
        this.runHighLevelBtn = document.getElementById('runHighLevelBtn');
        this.compileHighLevelBtn = document.getElementById('compileHighLevelBtn');
        
        // 纸带视图
        this.tapeView = document.getElementById('tapeView');
        
        // 标签页
        this.tabs = document.querySelectorAll('.tab');
        this.tabContents = document.querySelectorAll('.tab-content');
    }

    /**
     * 绑定事件监听器
     */
    bindEvents() {
        // 控制按钮
        this.startBtn.addEventListener('click', () => this.startExecution());
        this.pauseBtn.addEventListener('click', () => this.pauseExecution());
        this.stepBtn.addEventListener('click', () => this.stepExecution());
        this.resetBtn.addEventListener('click', () => this.resetMachine());
        this.haltBtn.addEventListener('click', () => this.haltMachine());
        
        // 速度控制
        this.speedSlider.addEventListener('input', () => this.updateSpeed());
        
        // 移动控制
        this.moveLeftBtn.addEventListener('click', () => this.moveHead(DIRECTION.LEFT));
        this.moveRightBtn.addEventListener('click', () => this.moveHead(DIRECTION.RIGHT));
        
        // 缓存操作
        this.loadToCacheBtn.addEventListener('click', () => this.loadToCache());
        this.writeFromCacheBtn.addEventListener('click', () => this.storeFromCache());
        this.clearCacheBtn.addEventListener('click', () => this.clearCache());
        this.editCacheBtn.addEventListener('click', () => this.editCache());
        
        // 数据输入
        this.writeDataBtn.addEventListener('click', () => this.writeData());
        this.byteSizeInput.addEventListener('change', () => this.changeByteSize());
        
        // 命令执行
        this.executeCommandBtn.addEventListener('click', () => this.executeCommand());
        this.addInstructionBtn.addEventListener('click', () => this.addInstruction());
        
        // 历史记录
        this.clearHistoryBtn.addEventListener('click', () => this.clearHistory());
        
        // 汇编执行
        this.runAssemblyBtn.addEventListener('click', () => this.runAssembly());
        this.compileAssemblyBtn.addEventListener('click', () => this.compileAssembly());
        
        // 高级语言
        this.runHighLevelBtn.addEventListener('click', () => this.runHighLevel());
        this.compileHighLevelBtn.addEventListener('click', () => this.compileHighLevel());
        
        // 标签页切换
        this.tabs.forEach(tab => {
            tab.addEventListener('click', () => this.switchTab(tab.dataset.tab));
        });
        
        // 窗口大小变化
        window.addEventListener('resize', () => this.drawTape());
    }

    /**
     * 更新UI状态
     */
    updateUI() {
        // 更新状态显示
        this.currentState.textContent = this.turingMachine.currentState;
        this.currentSymbol.textContent = this.turingMachine.read();
        this.headPosition.textContent = this.turingMachine.headPosition;
        this.stepCount.textContent = this.turingMachine.stepCount;
        this.byteSize.textContent = `${this.turingMachine.byteSize} 字节`;
        this.cacheSize.textContent = `${this.turingMachine.cache.length} 字节`;
        
        // 更新按钮状态
        this.pauseBtn.disabled = !this.isExecuting;
        this.startBtn.disabled = this.isExecuting || this.turingMachine.halted;
        this.haltBtn.disabled = this.turingMachine.halted;
        
        // 更新缓存显示
        this.updateCacheView();
        
        // 更新纸带显示
        this.drawTape();
        
        // 更新历史记录
        this.updateHistoryView();
        
        // 更新纸带视图
        this.updateTapeView();
    }

    /**
     * 绘制纸带可视化
     */
    drawTape() {
        const canvas = this.tapeCanvas;
        const ctx = this.tapeCtx;
        const cellWidth = 40;
        const cellHeight = 60;
        const visibleCells = Math.min(25, Math.floor(canvas.width / cellWidth));
        const startPos = Math.max(0, this.turingMachine.headPosition - Math.floor(visibleCells / 2));
        
        // 清除画布
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        
        // 绘制纸带背景
        ctx.fillStyle = '#f0f0f0';
        ctx.fillRect(0, 0, canvas.width, cellHeight);
        
        // 绘制单元格
        for (let i = 0; i < visibleCells; i++) {
            const pos = startPos + i;
            if (pos >= this.turingMachine.tape.length) break;
            
            const x = i * cellWidth;
            const isCurrent = pos === this.turingMachine.headPosition;
            
            // 绘制单元格边框
            ctx.strokeStyle = isCurrent ? '#ff0000' : '#cccccc';
            ctx.lineWidth = isCurrent ? 2 : 1;
            ctx.strokeRect(x, 0, cellWidth, cellHeight);
            
            // 绘制单元格内容
            ctx.fillStyle = '#000000';
            ctx.font = '14px Arial';
            ctx.textAlign = 'center';
            ctx.fillText(this.turingMachine.tape[pos], x + cellWidth / 2, cellHeight / 2 + 5);
            
            // 绘制位置编号
            ctx.fillStyle = '#666666';
            ctx.font = '10px Arial';
            ctx.fillText(pos.toString(), x + cellWidth / 2, cellHeight - 5);
        }
        
        // 绘制读写头
        const headX = (this.turingMachine.headPosition - startPos) * cellWidth + cellWidth / 2;
        ctx.beginPath();
        ctx.moveTo(headX, cellHeight);
        ctx.lineTo(headX - 10, cellHeight + 20);
        ctx.lineTo(headX + 10, cellHeight + 20);
        ctx.closePath();
        ctx.fillStyle = '#ff0000';
        ctx.fill();
    }

    /**
     * 更新缓存视图
     */
    updateCacheView() {
        if (this.turingMachine.cache.length === 0) {
            this.cacheView.textContent = '缓存为空';
            return;
        }
        
        this.cacheView.innerHTML = this.turingMachine.cache
            .map((value, index) => 
                `<div class="cache-item">
                    <span class="cache-index">[${index}]:</span>
                    <span class="cache-value">${value}</span>
                </div>`)
            .join('');
    }

    /**
     * 更新历史视图
     */
    updateHistoryView() {
        const history = getHistory();
        if (history.length === 0) {
            this.commandHistory.textContent = '没有执行历史';
            return;
        }
        
        this.commandHistory.innerHTML = history
            .slice().reverse()
            .map(item => 
                `<div class="history-item">
                    <span class="history-step">步骤 ${item.step}:</span>
                    <span class="history-instruction">${JSON.stringify(item.instruction)}</span>
                    <span class="history-time">${new Date(item.timestamp).toLocaleTimeString()}</span>
                </div>`)
            .join('');
    }

    /**
     * 更新纸带视图
     */
    updateTapeView() {
        const tape = this.turingMachine.tape;
        const headPos = this.turingMachine.headPosition;
        
        this.tapeView.innerHTML = tape
            .map((value, index) => 
                `<span class="tape-item ${index === headPos ? 'tape-current' : ''}">
                    ${index === headPos ? '▶' : ''}${index}: ${value}
                </span>`)
            .join('');
    }

    /**
     * 开始执行
     */
    startExecution() {
        if (this.isExecuting || this.turingMachine.halted) return;
        
        this.isExecuting = true;
        this.updateUI();
        this.executeLoop();
    }

    /**
     * 执行循环
     */
    executeLoop() {
        if (!this.isExecuting || this.turingMachine.halted) {
            this.isExecuting = false;
            return;
        }
        
        // 执行单步
        const instructions = loadInstructions();
        let executed = false;
        
        for (const instruction of instructions) {
            if (this.turingMachine.executeInstruction(instruction)) {
                executed = true;
                break;
            }
        }
        
        this.updateUI();
        
        if (!executed) {
            this.turingMachine.halt();
            this.isExecuting = false;
            console.warn('没有匹配的指令，图灵机已停机');
            return;
        }
        
        // 继续执行
        this.animationFrameId = setTimeout(
            () => this.executeLoop(),
            this.executionSpeed
        );
    }

    /**
     * 暂停执行
     */
    pauseExecution() {
        this.isExecuting = false;
        if (this.animationFrameId) {
            clearTimeout(this.animationFrameId);
            this.animationFrameId = null;
        }
        this.updateUI();
    }

    /**
     * 单步执行
     */
    stepExecution() {
        if (this.isExecuting || this.turingMachine.halted) return;
        
        const instructions = loadInstructions();
        let executed = false;
        
        for (const instruction of instructions) {
            if (this.turingMachine.executeInstruction(instruction)) {
                executed = true;
                break;
            }
        }
        
        if (!executed) {
            this.turingMachine.halt();
            console.warn('没有匹配的指令，图灵机已停机');
        }
        
        this.updateUI();
    }

    /**
     * 重置图灵机
     */
    resetMachine() {
        this.pauseExecution();
        this.turingMachine.reset();
        this.updateUI();
    }

    /**
     * 停机
     */
    haltMachine() {
        this.pauseExecution();
        this.turingMachine.halt();
        this.updateUI();
    }

    /**
     * 更新执行速度
     */
    updateSpeed() {
        const speed = parseInt(this.speedSlider.value);
        const speeds = [1000, 800, 600, 400, 200, 100, 50, 30, 20, 10];
        this.executionSpeed = speeds[speed - 1];
        
        const labels = ['最慢', '很慢', '慢', '稍慢', '中速', '稍快', '快', '很快', '极快', '最快'];
        this.speedValue.textContent = labels[speed - 1];
    }

    /**
     * 移动读写头
     * @param {'L'|'R'} direction 移动方向
     */
    moveHead(direction) {
        try {
            const steps = parseInt(this.moveSteps.value) || 1;
            this.turingMachine.move(direction, steps);
            this.updateUI();
        } catch (error) {
            console.warn(error.message);
        }
    }

    /**
     * 加载数据到缓存
     */
    loadToCache() {
        try {
            const position = parseInt(this.loadPosition.value);
            const length = parseInt(this.loadLength.value) || 1;
            this.turingMachine.loadToCache(position, length);
            this.updateUI();
        } catch (error) {
            console.warn(error.message);
        }
    }

    /**
     * 从缓存存储数据
     */
    storeFromCache() {
        try {
            const position = parseInt(this.writePosition.value);
            this.turingMachine.storeFromCache(position);
            this.updateUI();
        } catch (error) {
            console.warn(error.message);
        }
    }

    /**
     * 清空缓存
     */
    clearCache() {
        this.turingMachine.clearCache();
        this.updateUI();
    }

    /**
     * 编辑缓存
     */
    editCache() {
        const newValue = prompt('输入新的缓存值(用空格分隔多个字节):', this.turingMachine.cache.join(' '));
        if (newValue !== null) {
            try {
                const values = newValue.split(/\s+/).filter(v => v);
                if (values.some(v => !/^[0-9A-Fa-f]{2}$/.test(v))) {
                    throw new Error(ERROR_MESSAGES.INVALID_HEX_VALUE);
                }
                this.turingMachine.cache = values.map(v => v.toUpperCase());
                this.updateUI();
            } catch (error) {
                console.warn(error.message);
            }
        }
    }

    /**
     * 写入数据到纸带
     */
    writeData() {
      try {
          const inputValue = this.inputData.value.trim();
          const position = parseInt(this.inputPosition.value);
  
          // 验证位置是否合法
          if (position < 0 || position >= this.turingMachine.tape.length) {
              throw new Error(ERROR_MESSAGES.INVALID_POSITION);
          }
  
          // 移除所有空格，并确保长度为偶数（不足补0）
          const hexStr = inputValue.replace(/\s+/g, '');
          const paddedHexStr = hexStr.length % 2 === 0 ? hexStr : hexStr + '0';
  
          // 分割成每2个字符一组的数组
          const bytes = [];
          for (let i = 0; i < paddedHexStr.length; i += 2) {
              const byte = paddedHexStr.substr(i, 2).toUpperCase();
              
              // 验证是否为合法的十六进制值
              if (!/^[0-9A-F]{2}$/.test(byte)) {
                  throw new Error(ERROR_MESSAGES.INVALID_HEX_VALUE);
              }
              bytes.push(byte);
          }
  
          // 写入数据到磁带（不超过磁带长度）
          for (let i = 0; i < bytes.length && (position + i) < this.turingMachine.tape.length; i++) {
              this.turingMachine.tape[position + i] = bytes[i];
          }
  
          this.turingMachine.saveState();
          this.updateUI();
      } catch (error) {
          console.warn(error.message);
      }
  }
    /**
     * 改变字节大小
     */
    changeByteSize() {
        try {
            const size = parseInt(this.byteSizeInput.value);
            this.turingMachine.setByteSize(size);
            this.updateUI();
        } catch (error) {
            console.warn(error.message);
            this.byteSizeInput.value = this.turingMachine.byteSize;
        }
    }

    /**
     * 执行命令
     */
    executeCommand() {
        try {
            const commandText = this.commandInput.value.trim();
            if (!commandText) return;
            
            const command = JSON.parse(commandText.replace(/'/g, '"'));
            if (!this.turingMachine.validateInstruction(command)) {
                throw new Error(ERROR_MESSAGES.INVALID_INSTRUCTION);
            }
            
            if (!this.turingMachine.executeInstruction(command)) {
                console.warn('当前状态不匹配，指令未执行');
            }
            
            this.updateUI();
        } catch (error) {
            console.warn(`执行命令失败: ${error.message}`);
        }
    }

    /**
     * 添加指令到指令集
     */
    addInstruction() {
        try {
            const commandText = this.commandInput.value.trim();
            if (!commandText) return;
            
            const command = JSON.parse(commandText.replace(/'/g, '"'));
            if (!this.turingMachine.validateInstruction(command)) {
                throw new Error(ERROR_MESSAGES.INVALID_INSTRUCTION);
            }
            
            const instructions = loadInstructions();
            instructions.push(command);
            saveInstructions(instructions);
            
            console.warn('指令已添加到指令集');
        } catch (error) {
            console.warn(`添加指令失败: ${error.message}`);
        }
    }

    /**
     * 清除历史记录
     */
    clearHistory() {
        clearHistory();
        this.updateHistoryView();
    }

    /**
     * 运行汇编代码
     */
    runAssembly() {
        try {
            const assemblyCode = this.assemblyInput.value.trim();
            if (!assemblyCode) return;
            
        // 重置状态
        this.turingMachine.currentState = 'q0';  // 确保与汇编器初始状态一致
            this.assembler.reset();
            const instructions = this.assembler.assemble(assemblyCode);
            
            // 执行每条指令
            for (const instruction of instructions) {
                if (!this.turingMachine.executeInstruction(instruction)) {
                    console.warn('执行汇编指令时遇到错误' + instruction);
                    break;
                }
            }
            
            this.updateUI();
        } catch (error) {
            console.warn(`汇编执行失败: ${error.message}`);
        }
    }

    /**
     * 编译汇编代码
     */
    compileAssembly() {
        try {
            const assemblyCode = this.assemblyInput.value.trim();
            if (!assemblyCode) return;
            
            this.assembler.reset();
            const instructions = this.assembler.assemble(assemblyCode);
            
            // 显示编译结果
            this.commandInput.value = instructions
                .map(inst => JSON.stringify(inst))
                .join('\n');
            
            // 切换到命令标签页
            this.switchTab('command');
        } catch (error) {
            console.warn(`汇编编译失败: ${error.message}`);
        }
    }

    /**
     * 运行高级语言代码
     */
    runHighLevel() {
        console.warn('高级语言执行功能将在后续版本实现');
    }

    /**
     * 编译高级语言代码
     */
    compileHighLevel() {
        console.warn('高级语言编译功能将在后续版本实现');
    }

    /**
     * 切换标签页
     * @param {string} tabName 标签页名称
     */
    switchTab(tabName) {
        // 更新标签样式
        this.tabs.forEach(tab => {
            tab.classList.toggle('active', tab.dataset.tab === tabName);
        });
        
        // 更新内容显示
        this.tabContents.forEach(content => {
            content.classList.toggle('active', content.id === `${tabName}Tab`);
        });
    }
}

export default UIController;